From 1a8f3e2462829f8a186590a6ad6b7642309baa5b Mon Sep 17 00:00:00 2001 From: =?utf8?q?S=C3=A9bastien=20Wilmet?= Date: Thu, 26 Nov 2015 13:31:19 +0100 Subject: [PATCH] textiter: fix bug in case insensitive backward search 'win.lines' contains the same content as the GtkTextBuffer, so to find @match_start, forward_chars_with_skipping() is called with skip_decomp=FALSE (the last parameter). So far so good. On the other hand, the content 'lines' (the needle split in lines) is casefolded and normalized for a case insensitive search. So, forward_chars_with_skipping(..., skip_decomp=TRUE) must be called only for the portion of text containing the needle. Since 'start_tmp' contains the location at the start of the match, we can simply begin at that location to find the end of the match. Unit tests are added. https://bugzilla.gnome.org/show_bug.cgi?id=758698 --- gtk/gtktextiter.c | 23 ++++++++++------------- testsuite/gtk/textiter.c | 12 ++++++++++++ 2 files changed, 22 insertions(+), 13 deletions(-) diff --git a/gtk/gtktextiter.c b/gtk/gtktextiter.c index a863c38682..2496ea85bc 100644 --- a/gtk/gtktextiter.c +++ b/gtk/gtktextiter.c @@ -5309,37 +5309,34 @@ gtk_text_iter_backward_search (const GtkTextIter *iter, { /* Match! */ gint offset; - GtkTextIter next; GtkTextIter start_tmp; - + GtkTextIter end_tmp; + /* Offset to start of search string */ offset = g_utf8_strlen (*win.lines, first_line_match - *win.lines); - next = win.first_line_start; - start_tmp = next; + start_tmp = win.first_line_start; forward_chars_with_skipping (&start_tmp, offset, visible_only, !slice, FALSE); if (limit && gtk_text_iter_compare (limit, &start_tmp) > 0) goto out; /* match was bogus */ - + if (match_start) *match_start = start_tmp; /* Go to end of search string */ - l = lines; - while (*l) - { - offset += g_utf8_strlen (*l, -1); - ++l; - } + offset = 0; + for (l = lines; *l != NULL; l++) + offset += g_utf8_strlen (*l, -1); - forward_chars_with_skipping (&next, offset, + end_tmp = start_tmp; + forward_chars_with_skipping (&end_tmp, offset, visible_only, !slice, case_insensitive); if (match_end) - *match_end = next; + *match_end = end_tmp; retval = TRUE; goto out; diff --git a/testsuite/gtk/textiter.c b/testsuite/gtk/textiter.c index d05a8972de..51c209b5c6 100644 --- a/testsuite/gtk/textiter.c +++ b/testsuite/gtk/textiter.c @@ -186,6 +186,12 @@ test_search (void) check_found_backward ("This is some \303\240 text", "some \303\240", 0, 8, 14, "some \303\240"); check_found_backward ("This is some \303\240 text", "\303\240 text", 0, 13, 19, "\303\240 text"); check_found_backward ("This is some \303\240 text", "some \303\240 text", 0, 8, 19, "some \303\240 text"); + + /* multi-byte characters outside the needle */ + check_found_forward ("\303\200 aa", "aa", 0, 2, 4, "aa"); + check_found_forward ("aa \303\200", "aa", 0, 0, 2, "aa"); + check_found_backward ("\303\200 aa", "aa", 0, 2, 4, "aa"); + check_found_backward ("aa \303\200", "aa", 0, 0, 2, "aa"); } static void @@ -265,6 +271,12 @@ test_search_caseless (void) check_found_backward ("This is some Foo\nFoo text", "foo\nfoo", flags, 13, 20, "Foo\nFoo"); check_found_backward ("This is some \303\200\n\303\200 text", "\303\240\n\303\240", flags, 13, 16, "\303\200\n\303\200"); check_found_backward ("This is some \303\200\n\303\200 text", "a\314\200\na\314\200", flags, 13, 16, "\303\200\n\303\200"); + + /* multi-byte characters outside the needle */ + check_found_forward ("\303\200 aa", "aa", flags, 2, 4, "aa"); + check_found_forward ("aa \303\200", "aa", flags, 0, 2, "aa"); + check_found_backward ("\303\200 aa", "aa", flags, 2, 4, "aa"); + check_found_backward ("aa \303\200", "aa", flags, 0, 2, "aa"); } static void -- 2.30.2